package com.wnxy.sddfp.sms.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.wnxy.sddfp.sms.config.SmsTemplate;
import com.wnxy.sddfp.sms.service.SmsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.concurrent.TimeUnit;

@Service
public class SmsServiceImpl implements SmsService {

    @Autowired
    private SmsTemplate smsTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

        // 定义频率限制常量
        private static final String LOCK_KEY_PREFIX = "sms:lock:";  // 账号锁定键前缀
        private static final String COUNT_KEY_PREFIX = "sms:count:"; // 发送次数计数键前缀
        private static final int MAX_ATTEMPTS = 3;                   // 允许的最大发送次数
        private static final int LOCK_DURATION = 1;                  // 锁定时长（小时）
        private static final int COUNT_WINDOW = 1;                  // 计数窗口期（分钟）
    @Override
    public String sendCode(String phone) {



        //使用redis进行时间统计，判断是否频繁发送短信验证码，锁账号

        // 验证码还没有过期，直接返回
//        if (stringRedisTemplate.hasKey(phone)) {
//            return "验证码没有过期";
//        }
//        String code = RandomUtil.randomNumbers(4);
//
//        // 验证码存储到redis
//        stringRedisTemplate.opsForValue().set(phone, code, Duration.ofMinutes(5));
//
//        // 调用阿里云sms服务，发送验证码
//        //smsTemplate.sendSms(phone, code);
//
//        return "获取的验证码是:" + code;
//    }
        // 1. 检查账号是否被锁定
        String lockKey = LOCK_KEY_PREFIX + phone;
        if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(lockKey))) {
            return "请求过于频繁，账号已被锁定，请1小时后再试";
        }

        // 2. 检查验证码是否未过期
        if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(phone))) {
            return "验证码尚未过期，请勿重复获取";
        }

        // 3. 频率控制：检查发送次数
        String countKey = COUNT_KEY_PREFIX + phone;
        Long count = stringRedisTemplate.opsForValue().increment(countKey);
        // 首次发送时设置计数器的过期时间
        if (count != null && count == 1) {
            stringRedisTemplate.expire(countKey, COUNT_WINDOW, TimeUnit.MINUTES);
        }

        // 4. 超过阈值则锁定账号
        if (count != null && count > MAX_ATTEMPTS) {
            // 设置锁定并清除计数器
            stringRedisTemplate.opsForValue().set(lockKey, "locked", LOCK_DURATION, TimeUnit.HOURS);
            stringRedisTemplate.delete(countKey);
            return "操作过于频繁，账号已被锁定1小时";
        }

        // 5. 生成并发送验证码
        String code = RandomUtil.randomNumbers(4);
        stringRedisTemplate.opsForValue().set(phone, code, Duration.ofMinutes(5));
        // smsTemplate.sendSms(phone, code);  // 实际调用短信服务

        return "验证码已发送：" + code;
    }
}